import hashlib
import mimetypes
import random
import string
import uuid
import datetime
from datetime import datetime as dt
import jwt
from django.contrib.sites import requests
from django.core.paginator import Paginator
from django.db.models import Q
from django.forms import ModelForm, forms
from django.http import JsonResponse, HttpResponse, FileResponse
from .models import User
from django.views import View
import json
from django.conf import settings
from .serializers import *
from rest_framework.views import APIView
from rest_framework.response import Response  # 我还是用了drf这里，因为我看这样的话写POST的时候更简单一些
from django.utils import timezone
import time
from urllib.parse import parse_qs
import requests
from openpyxl import Workbook
import pandas as pd
import pytz
from bs4 import BeautifulSoup  # pip install beautifulsoup4
import requests
import datetime
import math
import re


def generate_random_string(length=10):
    """生成指定长度的随机字符串，包含字母和数字"""
    characters = string.ascii_letters + string.digits
    return ''.join(random.choice(characters) for _ in range(length))


def create_manager_token(man_id, timeout=10080):
    expire_time = timezone.now() + timedelta(minutes=timeout)
    payload = {
        'exp': expire_time,
        'id': man_id
    }
    result = jwt.encode(payload=payload, key=settings.SECRET_KEY, algorithm='HS256')
    return result


def create_user_token(openid, user_id, timeout=10080):  # 自定义token
    expire_time = timezone.now() + timedelta(minutes=timeout)
    payload = {
        'exp': expire_time,
        'openid': openid,
        'id': user_id
    }
    result = jwt.encode(payload=payload, key=settings.SECRET_KEY, algorithm='HS256')
    return result


def verify_token(token):  # 验证token函数
    result = {'status': False, 'data': None, 'error': None}
    try:
        verified_payload = jwt.decode(token, key=settings.SECRET_KEY, verify=False,
                                      algorithms=['HS256'])  # 这里verify需要改，但是调试阶段不需要
        result['status'] = True
        result['data'] = verified_payload
    except jwt.DecodeError:
        result['error'] = 'token认证失败'
    except jwt.InvalidTokenError:
        result['error'] = 'token失效或携带关键字错误'
    return result


def is_login_manager(token):  # 验证管理员登录情况的函数
    if not token:
        return {'code': 419, 'message': '未登录'}  # 处理未携带token的情况
    result = verify_token(token)
    if result.get('status'):
        temp = result['data']
        manager_id = temp['id']
        try:
            obj = Manager.objects.filter(id=manager_id).first()
        except Exception as e:
            return Response({'code': 500, "message": '用户不存在，token错误', "error": str(e)})
        if obj:
            return {'code': 200, 'message': '已登录'}
        else:
            return {'code': 404, 'message': "目标不存在"}
    else:
        return {'code': 400, "message": result.get('error')}


def is_login_supermanager(token):  # 验证超级管理员登录情况的函数
    if not token:
        return {'code': 419, 'message': '未登录'}  # 处理未携带token的情况
    result = verify_token(token)
    if result.get('status'):
        temp = result['data']
        manager_id = temp['id']
        if 0 < manager_id < 4:  # 我不打算新建一个类了，就让manager里面id值1-3的为超级管理员
            return {'code': 200, 'message': '超级管理员已登录'}
        else:
            return {'code': 404, 'message': "您不是超级管理员"}
    else:
        return {'code': 400, "message": result.get('error')}


def is_login_user(token):
    if not token:
        return {'code': 419, 'message': '未携带token'}  # 处理未携带token的情况
    try:
        result = verify_token(token)
    except Exception as e:
        return Response({'code': 500, "message": 'token错误', "error": str(e)})
    if result.get('status'):
        temp = result['data']
        user_id = temp['id']
        try:
            obj = User.objects.filter(id=user_id).first()
        except Exception as e:
            return Response({'code': 500, "message": '用户不存在，token错误', "error": str(e)})
        if obj:
            return {'code': 200, 'message': '已登录'}
        else:
            return {'code': 404, 'message': "用户不存在"}
    else:
        return {'code': 400, "message": result.get('error')}


class LoginDemo(APIView):
    def post(self, request):
        data = request.body.decode('utf-8')
        json_data = json.loads(data)
        user_openid = json_data.get('user_openid')
        obj = User.objects.filter(user_openid=user_openid).first()
        user_key = {
            'openid': user_openid,
            'id': obj.id,
        }
        if not obj:
            return Response({'code': 401, 'message': '登录失败'})
        else:
            token = create_user_token(obj.user_openid, obj.id)
            return Response({'code': 200, 'token': token, 'data': user_key, 'message': '登录成功'})


class LoginDemo2(APIView):
    def post(self, request):  # 参考下其他的，这里是要加self的
        # 获取微信登录凭证 code
        print(request)
        code = request.data.get('code')
        print(code)

        # 向微信服务器发送请求，获取用户的 openid 和 session_key
        params = {
            # 'appid': settings.AppId,
            'appid': 'wxa78169eeb3e130bc',
            # 'secret': settings.AppSecret,
            'secret': 'eb7112918a20263bf6517fffb92c9c4a',
            'js_code': code,
            'grant_type': 'authorization_code'
        }

        response = requests.get('https://api.weixin.qq.com/sns/jscode2session', params=params)
        data = response.json()
        print(data)

        # 处理获取到的用户信息
        if 'openid' in data:
            openid = data['openid']
            session_key = data['session_key']
            try:
                obj = User.objects.get(user_openid=openid)  # 是否存在该用户
            except Exception as e:
                obj = User.objects.create(  # 这样下面才能用obj.调用
                    user_openid=openid,
                )
                user_key = {
                    'openid': obj.user_openid,
                    'id': obj.id,
                    'session_key': session_key,
                    'token': create_user_token(obj.user_openid, obj.id)  # 这里也得要token的吧
                }
                return Response({'code': 200, 'isRegister': 0, 'data': user_key, 'message': '用户已创建'})
            else:
                user_key = {
                    'openid': obj.user_openid,
                    'id': obj.id,
                    'session_key': session_key,
                    'token': create_user_token(obj.user_openid, obj.id)
                }
                return Response({'code': 200, 'isRegister': 0, 'data': user_key, 'message': '获取成功！'})
        else:
            # 处理错误情况
            return Response({'error': 'Failed to get openid and session_key'})


class wx_login(APIView):
    def post(self, request):  # 参考下其他的，这里是要加self的
        # 获取微信登录凭证 code
        print(request)
        code = request.data.get('code')
        print(code)

        # 向微信服务器发送请求，获取用户的 openid 和 session_key
        params = {
            # 'appid': settings.AppId,
            'appid': 'wxa78169eeb3e130bc',
            # 'secret': settings.AppSecret,
            'secret': 'eb7112918a20263bf6517fffb92c9c4a',
            'js_code': code,
            'grant_type': 'authorization_code'
        }

        response = requests.get('https://api.weixin.qq.com/sns/jscode2session', params=params)
        data = response.json()
        print(data)

        # 处理获取到的用户信息
        if 'openid' in data:
            openid = data['openid']
            session_key = data['session_key']
            try:
                obj = User.objects.get(user_openid=openid)  # 是否存在该用户
            except Exception as e:
                obj = User.objects.create(  # 这样下面才能用obj.调用
                    user_openid=openid,
                )
                user_key = {
                    'openid': obj.user_openid,
                    'id': obj.id,
                    'session_key': session_key,
                    'token': create_user_token(obj.user_openid, obj.id)  # 这里也得要token的吧
                }
                return Response({'code': 200, 'isRegister': 0, 'data': user_key, 'message': '用户已创建'})
            else:
                user_key = {
                    'openid': obj.user_openid,
                    'id': obj.id,
                    'session_key': session_key,
                    'token': create_user_token(obj.user_openid, obj.id)
                }
                return Response({'code': 200, 'isRegister': 1, 'data': user_key, 'message': '获取成功！'})
        else:
            # 处理错误情况
            return Response({'error': 'Failed to get openid and session_key'})


class UserInfo(APIView):
    def get(self, request):
        token = request.headers.get('Authorization')
        login_status = is_login_user(token)
        if login_status['code'] == 200:
            result = verify_token(token)
            aa = result['data']
            user_id = aa['id']
            try:
                obj = User.objects.get(id=user_id)
                avatar_url = obj.user_image.url if obj.user_image else None
                user_key1 = {
                    'avatarUrl': "https://api.kuangqiaodongjie.cn" + avatar_url,
                    'nickName': obj.user_nick
                }
                print(user_key1)
            except Exception as e:
                return Response({'code': 500, "message": '获取用户昵称和头像出错', "error": str(e)})
            return Response({
                'code': 200,
                'data': user_key1,
                'message': '获取用户所有表单成功'
            })
        else:
            return Response(login_status)

    def post(self, request):
        token = request.headers.get('Authorization')
        login_status = is_login_user(token)
        if login_status['code'] == 200:
            result = verify_token(token)
            aa = result['data']
            user_id = aa['id']
            try:
                avatar = request.FILES.get('avatarUrl')
                nickname = request.POST.get('nickName')
                if avatar:
                    # 获取 id=1 的用户对象
                    try:
                        user = User.objects.filter(id=user_id).first()  # 获取 id 的用户，若不存在返回 None
                    except Exception as e:
                        return Response({'code': 404, "message": '用户未找到', "error": str(e)})
                    # 将上传的图片赋值给用户的 user_image 字段
                    user.user_image = avatar
                    # 如果有昵称，更新昵称
                    if nickname:
                        user.user_nick = nickname
                    # 保存用户对象，更新数据库中的头像和昵称
                    user.save()
            except Exception as e:
                return Response({'code': 500, "message": '管理数据未获取', "error": str(e)})
            return Response({'code': 200, 'message': '上传头像和图片成功'})
        else:
            return Response(login_status)


class UserInfoTest(APIView):
    def get(self, request):
        # token = request.headers.get('Authorization')
        # login_status = is_login_user(token)
        # if login_status['code'] == 200:
        #     result = verify_token(token)
        #     aa = result['data']
        #     user_id = aa['id']
        try:
            obj = User.objects.get(id=1)
            avatar_url = obj.user_image.url if obj.user_image else None
            user_key1 = {
                'avatarUrl': "https://api.kuangqiaodongjie.cn" + avatar_url,
                'nickName': obj.user_nick
            }
            print(user_key1)
        except Exception as e:
            return Response({'code': 500, "message": '获取用户昵称和头像出错', "error": str(e)})
        return Response({
            'code': 200,
            'data': user_key1,
            'message': '获取用户所有表单成功'
        })

    # else:
    #     return Response(login_status)

    def post(self, request):
        # token = request.headers.get('Authorization')
        # login_status = is_login_user(token)
        # if login_status['code'] == 200:
        #     result = verify_token(token)
        #     aa = result['data']
        #     user_id = aa['id']
        try:
            avatar = request.FILES.get('avatarUrl')
            nickname = request.POST.get('nickName')
            if avatar:
                # 获取 id=1 的用户对象
                try:
                    user = User.objects.filter(id=1).first()  # 获取 id 的用户，若不存在返回 None
                except Exception as e:
                    return Response({'code': 404, "message": '用户未找到', "error": str(e)})
                # 将上传的图片赋值给用户的 user_image 字段
                user.user_image = avatar
                # 如果有昵称，更新昵称
                if nickname:
                    user.user_nick = nickname
                # 保存用户对象，更新数据库中的头像和昵称
                user.save()
        except Exception as e:
            return Response({'code': 500, "message": '管理数据未获取', "error": str(e)})
        return Response({'code': 200, 'message': '上传头像和图片成功'})
    # else:
    #     return Response(login_status)


class SuggForm(ModelForm):  # 比较简洁的表单写法
    class Meta:
        model = Suggestion
        fields = ['sugg_name', 'sugg_text', 'sugg_user_tele', 'sugg_site',
                  'sugg_sub_id', 'sugg_title', 'sugg_treat']  # sugg_sub_id得填提交建议的用户的主键


class CompForm(ModelForm):  # 比较简洁的表单写法
    class Meta:
        model = Complaint
        fields = ['comp_name', 'comp_text', 'comp_user_tele', 'comp_site',
                  'comp_sub_id', 'comp_title', 'comp_treat']


class UserForm(ModelForm):
    class Meta:
        model = User
        fields = ['id', 'user_openid', 'user_nick', 'user_tele', 'user_info', 'user_image', 'user_address']


def handle_uploaded_image(image_file):  # 处理文件，赋给新的路径
    # 构造要保存图片的路径
    timestamp = str(int(timezone.now().timestamp() * 1000)) + generate_random_string(8)
    # 获取上传文件的扩展名
    file_extension = os.path.splitext(image_file.name)[1]
    # 构建保存图片的路径，并将时间戳和原始扩展名拼接在一起作为文件名
    save_path = os.path.join(settings.MEDIA_ROOT, 'files', timestamp + file_extension)
    # 确保目录存在
    save_dir = os.path.dirname(save_path)  # 提取父目录路径
    if not os.path.exists(save_dir):
        try:
            os.makedirs(save_dir)  # 创建目录
            print(f"创建目录: {save_dir}")
        except OSError as e:
            print(f"创建目录时出错: {e}")

    # 检查是否有写权限
    if not os.access(save_dir, os.W_OK):
        print(f"没有写权限: {save_dir}")
    # 打开文件并保存
    try:
        with open(save_path, 'wb+') as destination:
            for chunk in image_file.chunks():
                destination.write(chunk)
    except Exception as e:
        print(f"保存文件时出错: {e}")
        return None

    return save_path


class ManagerLogin(APIView):  # Manager视图完成，所有功能验证，这里更改密码需要输入确认密码，不允许更改用户名，第一次默认密码为123456
    def post(self, request):
        try:
            data = request.body.decode('utf-8')
            json_data = json.loads(data)
            manager_account = json_data.get('manager_account')
            manager_code = json_data.get('manager_code')
        except Exception as e:
            return Response({'code': 500, "message": '管理登录数据出错', "error": str(e)})

        encry = hashlib.md5()  # 实例化md5
        encry.update(manager_code.encode())  # 字符串字节加密
        manager_pwd = encry.hexdigest()
        try:
            obj = Manager.objects.filter(manager_account=manager_account, manager_code=manager_pwd).first()
        except Exception as e:
            return Response({'code': 500, "message": '管理数据未获取', "error": str(e)})
        if not obj:
            return Response({'code': 401, 'message': '登录失败'})
        else:
            token = create_manager_token(obj.id)
            return Response({'code': 200, 'token': token, 'message': '登录成功'})


class ManagerDetail(APIView):
    def get(self, request):
        # 应该不用再传主键了，依据token里的信息给具体信息就行了
        # 我写了个判断登录状态的函数，这样就不用一遍一遍写大段的代码了
        token = request.headers.get('Authorization')
        login_status = is_login_manager(token)
        if login_status['code'] == 200:
            result = verify_token(token)
            aa = result['data']
            manager_id = aa['id']
            try:
                obj = Manager.objects.filter(id=manager_id).first()
                ser = ManagerSerializer(instance=obj, many=False)
            except Exception as e:
                return Response({'code': 500, "message": '管理信息数据获取出错', "error": str(e)})
            return Response({"code": 200, "data": ser.data})
        else:
            return Response(login_status)

    def put(self, request):
        # 同样不用传入主键了
        token = request.headers.get('Authorization')
        login_status = is_login_manager(token)
        if login_status['code'] == 200:
            result = verify_token(token)
            aa = result['data']
            manager_id = aa['id']
            data = request.body.decode('utf-8')
            try:
                json_data = json.loads(data)
                manager_name = json_data.get('manager_name')
                manager_tele = json_data.get('manager_tele')
                manager_account = json_data.get('manager_account')
                manager_code = json_data.get('manager_code')
                manager_recode = json_data.get('manager_recode')
            except Exception as e:
                return Response({'code': 500, "message": '管理信息格式错误', "error": str(e)})
            # 这里改了下，要不然我只填了姓名的话，最后数据库里电话就为null了（只能让管理员一次就该一个字段了）
            if manager_name and manager_tele and manager_account:
                try:
                    Manager.objects.filter(id=manager_id).update(manager_name=manager_name, manager_tele=manager_tele,
                                                                 manager_account=manager_account)
                except Exception as e:
                    return Response({'code': 500, "message": '管理登录数据出错', "error": str(e)})
                return Response({'code': 200, 'message': '修改成功'})
            elif manager_code or manager_recode:
                if manager_code == manager_recode:
                    encry = hashlib.md5()  # 实例化md5
                    encry.update(manager_code.encode())  # 字符串字节加密
                    manager_pwd = encry.hexdigest()
                    try:
                        Manager.objects.filter(id=manager_id).update(manager_code=manager_pwd)
                    except Exception as e:
                        return Response({'code': 500, "message": '管理密码保存出错', "error": str(e)})
                    return Response({'code': 200, 'message': '修改密码成功'})
                else:
                    return Response({'code': 400, 'message': '两次密码不一致'})
            else:
                return Response({'code': 400, 'message': '无信息'})
        else:
            return Response(login_status)

    def post(self, request):
        # 获取 Authorization token
        token = request.headers.get('Authorization')

        # 验证 token
        login_status = is_login_manager(token)
        if login_status['code'] == 200:
            result = verify_token(token)
            aa = result['data']
            manager_id = aa['id']
        else:
            return Response(login_status)
        # 获取删除的目标管理员的 ID
        target_manager_id = request.data.get('manager_id')  # 假设前端请求中包含要删除的 manager_id
        if not target_manager_id:
            return Response({'code': 400, 'message': '缺少 manager_id 参数'}, status=400)
        try:
            # 查找要删除的管理员对象
            manager_operate = Manager.objects.get(id=manager_id)
            manager_to_delete = Manager.objects.get(id=target_manager_id)

            # 检查是否有权限删除该管理员
            if manager_id == 1:
                # 执行删除
                manager_to_delete.delete()
                return Response({'code': 200, 'message': '管理员删除成功'})
            elif manager_operate.role and manager_to_delete.role == False:
                manager_to_delete.delete()
                return Response({'code': 200, 'message': '管理员删除成功'})
            else:
                return Response({'code': 403, 'message': '权限不足，无法删除该管理员'}, status=403)
        except Exception as e:
            return Response({'code': 500, 'message': '删除失败', 'error': str(e)}, status=500)


def GenerateCode(length=8):
    # 使用 ascii_letters 和 digits 生成随机字符串
    characters = string.ascii_letters + string.digits
    return ''.join(random.choice(characters) for _ in range(length))


class ManagerReset(APIView):
    def post(self, request):
        # 获取 Authorization token
        token = request.headers.get('Authorization')
        # 验证 token
        login_status = is_login_manager(token)
        if login_status['code'] == 200:
            try:
                target_manager_id = request.data.get('manager_id')
                manager = Manager.objects.get(id=target_manager_id)
                manager_code = GenerateCode(8)
                encry = hashlib.md5()  # 实例化md5
                encry.update(manager_code.encode())  # 字符串字节加密
                manager_pwd = encry.hexdigest()
                manager.manager_code = manager_pwd
                manager.save()
                result = {
                    'manager_code': manager_code,
                    'manager_account': manager.manager_account
                }
                return Response({'code': 200, 'data': result, 'message':'重置成功'})
            except Exception as e:
                return Response({'code': 500, 'message': '数据有误', 'error': str(e)}, status=500)
        else:
            return Response(login_status)


class ManagerAdd(APIView):
    def post(self, request):
        token = request.headers.get('Authorization')
        login_status = is_login_supermanager(token)
        if login_status['code'] == 200:
            try:
                data = request.body.decode('utf-8')
                json_data = json.loads(data)
                manager_account = json_data.get('manager_account')
                manager_code = json_data.get('manager_code')
                manager_role = json_data.get('manager_role')
            except Exception as e:
                return Response({'code': 500, "message": '添加管理数据格式错误', "error": str(e)})

            encry = hashlib.md5()
            encry.update(manager_code.encode())  # 字符串字节加密
            manager_pwd = encry.hexdigest()
            if manager_account and manager_pwd:
                try:
                    Manager.objects.create(manager_account=manager_account, manager_code=manager_pwd,
                                           role=manager_role)
                except Exception as e:
                    return Response({'code': 500, "message": '管理创建出错', "error": str(e)})
                return Response({'code': 200, "message": '增加管理员成功'})
            else:
                return Response({'code': 400, "message": '增加管理员失败'})
        else:
            return Response(login_status)


class ManagerAll(APIView):
    def get(self, request):
        # 获取 Authorization token
        token = request.headers.get('Authorization')
        login_status = is_login_supermanager(token)

        if login_status['code'] == 200:
            result = verify_token(token)
            aa = result['data']
            manager_id = aa['id']

            try:
                # 获取分页参数
                pagenum = int(request.GET.get('pagenum'))  # 默认第1页
                pagesize = int(request.GET.get('pagesize'))  # 默认每页10条
            except ValueError:
                return Response({'code': 400, 'message': '分页参数无效'}, status=400)

            # 根据权限不同查询 Manager
            if manager_id == 1:
                params = Manager.objects.exclude(id=manager_id).order_by('id')
            else:
                manager = Manager.objects.filter(id=manager_id).first()
                if manager and manager.role:
                    params = Manager.objects.filter(role=False).order_id('id')
                else:
                    return Response({'code': 404, 'message': "权限不足"})

            # 分页查询 Manager
            paginator = Paginator(params, pagesize)
            try:
                page_data = paginator.page(pagenum)
            except Exception as e:
                return Response({'code': 500, 'message': f'分页出错: {str(e)}'}, status=500)

            if page_data:
                ser = ManagerSerializer(instance=page_data, many=True)
                result = {
                    'code': 200,
                    'data': ser.data,
                    'message': '获取普通管理成功',
                    'total': paginator.count,  # 数据总条数
                    'total_pages': paginator.num_pages,  # 总页数
                    'pagenum': pagenum,  # 当前页码
                    'pagesize': pagesize,  # 每页条数
                }
                return Response(result)
            else:
                return Response({'code': 404, 'message': "未找到普通管理"})
        else:
            return Response(login_status)


class SuggestionAll(APIView):
    def get(self, request):  # 这里的get为管理员查询
        token = request.headers.get('Authorization')
        login_status = is_login_manager(token)
        if login_status['code'] == 200:
            try:
                try:
                    # 获取前端分页参数
                    pagenum = int(request.GET.get('pagenum'))  # 当前页码，默认为第1页
                    pagesize = int(request.GET.get('pagesize'))  # 每页条数，默认为10条
                except ValueError:
                    return Response({'code': 400, 'message': '分页参数无效'}, status=400)
                params = Suggestion.objects.filter(sugg_status=False).order_by('-id')
                # 使用 Paginator 进行分页
                paginator = Paginator(params, pagesize)
                try:
                    # 获取当前页的数据
                    page_data = paginator.page(pagenum)
                except Exception as e:
                    return Response({'code': 500, 'message': f'分页出错: {str(e)}'}, status=500)
                if page_data:
                    ser = SuggestionSerializer_list(instance=page_data, many=True)
                    # 构造分页返回结果
                    result = {
                        'code': 200,
                        'data': ser.data,
                        'message': '获取未处理表单成功',
                        'total': paginator.count,  # 数据总条数
                        'total_pages': paginator.num_pages,  # 总页数
                        'pagenum': pagenum,  # 当前页码
                        'pagesize': pagesize,  # 每页条数
                    }
                    return Response(result)
                else:
                    return Response({'code': 404, 'message': "未找到未处理表单"})
            except Exception as e:
                return Response({'code': 500, 'message': f'未知错误: {str(e)}'})
        else:
            return Response(login_status)


class SuggestionTreat(APIView):  # 第二次回传，要通过两次筛选，筛选未处理且标志位为1的表单，要注意此时序列化器
    def get(self, request):
        token = request.headers.get('Authorization')
        login_status = is_login_manager(token)
        if login_status['code'] == 200:
            try:
                # 获取前端分页参数
                pagenum = int(request.GET.get('pagenum'))  # 当前页码，默认为第1页
                pagesize = int(request.GET.get('pagesize'))  # 每页条数，默认为10条
            except ValueError:
                return Response({'code': 400, 'message': '分页参数无效'}, status=400)
            try:
                params1 = Suggestion.objects.filter(sugg_status=True).all()
                if params1:
                    params2 = Suggestion.objects.filter(sugg_treat=1).filter(sugg_status=True).all()
                    if params2:
                        params = params2.order_by('-id')
                    else:
                        return Response({'code': 404, 'message': "未找到回访未处理表单"})
                else:
                    return Response({'code': 404, 'message': "未找到表单"})
                # 使用 Paginator 进行分页
                paginator = Paginator(params, pagesize)
            except Exception as e:
                return Response({'code': 500, 'message': f'获取数据出错: {str(e)}'}, status=500)
            try:
                # 获取当前页的数据
                page_data = paginator.page(pagenum)
            except Exception as e:
                return Response({'code': 500, 'message': f'分页出错: {str(e)}'}, status=500)
            if page_data:
                ser = SuggestionSerializer_list(instance=page_data, many=True)
                # 构造分页返回结果
                result = {
                    'code': 200,
                    'data': ser.data,
                    'message': '获取未处理表单成功',
                    'total': paginator.count,  # 数据总条数
                    'total_pages': paginator.num_pages,  # 总页数
                    'pagenum': pagenum,  # 当前页码
                    'pagesize': pagesize,  # 每页条数
                }
                return Response(result)
            else:
                return Response({'code': 404, 'message': "未找到未处理表单"})
        else:
            return Response(login_status)


class SuggestionTreatWhich(APIView):
    def put(self, request, pk):
        token = request.headers.get('Authorization')
        login_status = is_login_manager(token)
        if login_status['code'] == 200:
            try:
                obj = Suggestion.objects.get(pk=pk)
            except Exception as e:
                return Response(
                    {'code': 404, "message": '未找到相应回访表', "error": str(e)})  # 这个类型报错很好用，可以直接返回错误信息，便于调试
            try:
                ser = SuggestionTreatSerializer(instance=obj, data=request.data)
            except Exception as e:
                return Response({'code': 400, "message": '未完成更新', "error": str(e)})
            if ser.is_valid():
                ser.save()
                return Response({'code': 200, 'data': ser.data, 'message': '回访成功'})
            else:
                return Response({'code': 400, 'massage': ser.errors})
        else:
            return Response(login_status)


class SuggestionListDetail(APIView):
    def get(self, request, pk):
        token = request.headers.get('Authorization')
        login_status = is_login_manager(token)
        if login_status['code'] == 200:
            params = Suggestion.objects.filter(pk=pk).all()
            if params:
                try:
                    ser = SuggestionSerializer(instance=params, many=True)
                    return Response({'code': 200, 'data': ser.data, "message": '获取某一表单成功'})
                except Exception as e:
                    return Response({'code': 404, "message": '返回失败', "error": str(e)})
            else:
                return Response({'code': 404, 'message': '无未处理的投诉'})
        else:
            return Response(login_status)

    def put(self, request, pk):
        token = request.headers.get('Authorization')
        login_status = is_login_manager(token)

        if login_status['code'] != 200:
            return Response(login_status)

        try:
            obj = Suggestion.objects.get(pk=pk)
        except Exception as e:
            return Response({'code': 404, "message": '未找到相应投诉表', "error": str(e)})
        try:
            ser = SuggestionFeedbackSerializer(instance=obj, data=request.data)
        except Exception as e:
            return Response({'code': 400, "message": '投诉表序列化出错', "error": str(e)})
        if ser.is_valid():
            try:
                ser.save()
                return Response({'code': 200, 'data': ser.data, 'message': '修改投诉表成功'})
            except Exception as e:
                return Response({'code': 400, "message": '投诉表保存出错', "error": str(e)})
        else:
            return Response({'code': 400, 'message': ser.errors})


class SuggestionUser(APIView):
    def post(self, request):
        token = request.headers.get('Authorization')
        login_status = is_login_user(token)
        if login_status['code'] == 200:
            form = SuggForm(request.POST)
            images = request.FILES.getlist('sugg_media')
            if form.is_valid():
                try:
                    # 保存表单数据
                    suggestion_instance = form.save()
                except Exception as e:
                    return Response({'code': 500, 'message': '表单保存失败', 'error': str(e)})

                if images:
                    try:
                        for image_file in images:
                            # 直接将文件对象传递给 ImageField，文件名由 upload_to 函数处理
                            suggestion_media = SuggestionMedia(sugg_media=image_file, sugg_list=suggestion_instance)
                            suggestion_media.save()
                    except Exception as e:
                        return Response({'code': 500, 'message': '图片保存失败', 'error': str(e)})

                    return Response({'code': 200, 'message': '提交图片和表单成功'})
                else:
                    return Response({'code': 200, 'data': form.data, 'message': '提交成功'})
            else:
                return Response({'code': 400, 'message': form.errors})
        else:
            return Response(login_status)


class UpLoadSPicture(APIView):
    def post(self, request, pk):
        token = request.headers.get('Authorization')
        login_status = is_login_user(token)
        if login_status['code'] == 200:
            try:
                images = request.FILES.get('sugg_media')
            except Exception as e:
                return Response({'code': 500, 'message': '图片获取失败', 'error': str(e)})
            try:
                obj = Suggestion.objects.get(pk=pk)
                if images:
                    suggestion_handle_media = SuggestionHandleMedia(sugg_handle_media=images, sugg_handle_list=obj)
                    suggestion_handle_media.save()
                    return Response({'code': 200, 'message': "图片上传成功"})
                else:
                    return Response({'code': 400, 'message': '图片获取失败'})
            except Exception as e:
                return Response({'code': 500, 'message': '图片保存失败', 'error': str(e)})

        else:
            return Response(login_status)


class UpLoadCPicture(APIView):
    def post(self, request, pk):
        token = request.headers.get('Authorization')
        login_status = is_login_user(token)
        if login_status['code'] == 200:
            try:
                images = request.FILES.get('comp_media')
            except Exception as e:
                return Response({'code': 500, 'message': '图片获取失败', 'error': str(e)})
            try:
                obj = Complaint.objects.get(pk=pk)
                if images:
                    complaint_handle_media = ComplaintHandleMedia(comp_handle_media=images, comp_handle_list=obj)
                    complaint_handle_media.save()
                    return Response({'code': 200, 'message': "图片上传成功"})
                else:
                    return Response({'code': 400, 'message': '图片获取失败'})
            except Exception as e:
                return Response({'code': 500, 'message': '图片保存失败', 'error': str(e)})

        else:
            return Response(login_status)


class SuggestionWhich(APIView):
    def get(self, request, pk):
        token = request.headers.get('Authorization')
        login_status = is_login_user(token)  # 用户使用某个表单查询
        if login_status['code'] == 200:
            try:
                obj = Suggestion.objects.filter(pk=pk).prefetch_related('suggestionmedia_set').all()
                ser = SuggestionSerializer(instance=obj, many=True, context={'request': request})
            except Exception as e:
                return Response({'code': 500, "message": '用户具体表单获取数据出错', "error": str(e)})
            return Response({'code': 200, 'data': ser.data, 'message': '获取列表成功'})
        else:
            return Response(login_status)

    def put(self, request, pk):  # 用户进行评价的函数
        token = request.headers.get('Authorization')
        login_status = is_login_user(token)
        if login_status['code'] == 200:
            try:
                data = json.loads(request.body)
                feedback = data.get('sugg_feedback', None)
            except Exception as e:
                return Response({'code': 500, "message": '提交修改数据格式出错', "error": str(e)})
            if feedback is not None:
                try:
                    obj = Suggestion.objects.get(pk=pk)
                    obj.sugg_feedback = feedback
                    obj.save()
                except Exception as e:
                    return Response({'code': 500, "message": '用户反馈数据保存失败', "error": str(e)})
                return Response({'code': 200, 'data': feedback, 'message': '评价成功！'})
            else:
                return Response({'code': 400, 'message': '评价错误'})
        else:
            return Response(login_status)


class SuggestionUserDetail(APIView):  # 查询本人提交的所有建议
    def get(self, request):
        token = request.headers.get('Authorization')
        login_status = is_login_user(token)
        if login_status['code'] == 200:
            try:
                result = verify_token(token)
                aa = result['data']
                user_id = aa['id']
                obj = Suggestion.objects.filter(sugg_sub_id=user_id).prefetch_related('suggestionmedia_set').all()
            except Exception as e:
                return Response({'code': 500, "message": '用户建议表数据获取出错', "error": str(e)})
            if obj:
                ser = SuggestionSerializer(instance=obj, many=True, context={'request': request})
                return Response({'code': 200, 'data': ser.data, 'message': '查询到用户的所有建议'})
            else:
                return Response({'code': 404, 'message': '该用户未提交任何建议'})
        else:
            return Response(login_status)


class ComplaintAll(APIView):  # 第一次回传，获取的只是未处理的表单，要注意这时候的序列化器
    def get(self, request):
        token = request.headers.get('Authorization')
        login_status = is_login_manager(token)
        if login_status['code'] == 200:
            try:
                try:
                    # 获取前端分页参数
                    pagenum = int(request.GET.get('pagenum'))  # 当前页码，默认为第1页
                    pagesize = int(request.GET.get('pagesize'))  # 每页条数，默认为10条
                except ValueError:
                    return Response({'code': 400, 'message': '分页参数无效'}, status=400)
                params = Complaint.objects.filter(comp_status=False).order_by('-id')
                # 使用 Paginator 进行分页
                paginator = Paginator(params, pagesize)
                try:
                    # 获取当前页的数据
                    page_data = paginator.page(pagenum)
                except Exception as e:
                    return Response({'code': 500, 'message': f'分页出错: {str(e)}'}, status=500)
                if page_data:
                    ser = ComplaintSerializer_list(instance=page_data, many=True)
                    # 构造分页返回结果
                    result = {
                        'code': 200,
                        'data': ser.data,
                        'message': '获取未处理表单成功',
                        'total': paginator.count,  # 数据总条数
                        'total_pages': paginator.num_pages,  # 总页数
                        'pagenum': pagenum,  # 当前页码
                        'pagesize': pagesize,  # 每页条数
                    }
                    return Response(result)
                else:
                    return Response({'code': 404, 'message': "未找到未处理表单"})
            except Exception as e:
                return Response({'code': 500, 'message': f'未知错误: {str(e)}'})
        else:
            return Response(login_status)


class ComplaintTreat(APIView):  # 第二次回传，要通过两次筛选，筛选未处理且标志位为1的表单，要注意此时序列化器
    def get(self, request):
        token = request.headers.get('Authorization')
        login_status = is_login_manager(token)
        if login_status['code'] == 200:
            try:
                # 获取前端分页参数
                pagenum = int(request.GET.get('pagenum'))  # 当前页码，默认为第1页
                pagesize = int(request.GET.get('pagesize'))  # 每页条数，默认为10条
            except ValueError:
                return Response({'code': 400, 'message': '分页参数无效'}, status=400)
            try:
                params1 = Complaint.objects.filter(comp_status=True).all()
                if params1:
                    params2 = Complaint.objects.filter(comp_treat=1).filter(comp_status=True).all()
                    if params2:
                        params = params2.order_by('-id')
                    else:
                        return Response({'code': 404, 'message': "未找到回访未处理表单"})
                else:
                    return Response({'code': 404, 'message': "未找到表单"})
                # 使用 Paginator 进行分页
                paginator = Paginator(params, pagesize)
            except Exception as e:
                return Response({'code': 500, 'message': f'获取数据出错: {str(e)}'}, status=500)
            try:
                # 获取当前页的数据
                page_data = paginator.page(pagenum)
            except Exception as e:
                return Response({'code': 500, 'message': f'分页出错: {str(e)}'}, status=500)
            if page_data:
                ser = ComplaintSerializer_list(instance=page_data, many=True)
                # 构造分页返回结果
                result = {
                    'code': 200,
                    'data': ser.data,
                    'message': '获取未处理表单成功',
                    'total': paginator.count,  # 数据总条数
                    'total_pages': paginator.num_pages,  # 总页数
                    'pagenum': pagenum,  # 当前页码
                    'pagesize': pagesize,  # 每页条数
                }
                return Response(result)
            else:
                return Response({'code': 404, 'message': "未找到未处理表单"})
        else:
            return Response(login_status)


class ComplaintTreatWhich(APIView):
    def put(self, request, pk):
        token = request.headers.get('Authorization')
        login_status = is_login_manager(token)
        if login_status['code'] == 200:
            try:
                obj = Complaint.objects.get(pk=pk)
            except Exception as e:
                return Response(
                    {'code': 404, "message": '未找到相应回访表', "error": str(e)})  # 这个类型报错很好用，可以直接返回错误信息，便于调试
            ser = ComplaintTreatSerializer(instance=obj, data=request.data)
            if ser.is_valid():
                ser.save()
                return Response({'code': 200, 'data': ser.data, 'message': '回访成功'})
            else:
                return Response({'code': 400, 'massage': ser.errors})
        else:
            return Response(login_status)


class ComplaintListDetail(APIView):
    def get(self, request, pk):
        token = request.headers.get('Authorization')
        login_status = is_login_manager(token)
        if login_status['code'] == 200:
            params = Complaint.objects.filter(pk=pk).all()
            if params:
                try:
                    ser = ComplaintSerializer(instance=params, many=True)
                    return Response({'code': 200, 'data': ser.data, "message": '获取某一表单成功'})
                except Exception as e:
                    return Response({'code': 404, "message": '返回失败', "error": str(e)})
            else:
                return Response({'code': 404, 'message': '无未处理的投诉'})
        else:
            return Response(login_status)

    def put(self, request, pk):
        token = request.headers.get('Authorization')
        login_status = is_login_manager(token)

        if login_status['code'] != 200:
            return Response(login_status)

        try:
            obj = Complaint.objects.get(pk=pk)
        except Exception as e:
            return Response({'code': 404, "message": '未找到相应投诉表', "error": str(e)})
        try:
            ser = ComplaintFeedbackSerializer(instance=obj, data=request.data)
        except Exception as e:
            return Response({'code': 400, "message": '投诉表序列化出错', "error": str(e)})
        if ser.is_valid():
            try:
                ser.save()
                return Response({'code': 200, 'data': ser.data, 'message': '修改投诉表成功'})
            except Exception as e:
                return Response({'code': 400, "message": '投诉表保存出错', "error": str(e)})
        else:
            return Response({'code': 400, 'message': ser.errors})


class ComplaintUser(APIView):
    def post(self, request):
        token = request.headers.get('Authorization')
        login_status = is_login_user(token)
        if login_status['code'] == 200:
            form = CompForm(request.POST)
            images = request.FILES.getlist('comp_media')
            print(form)
            print(images)
            if form.is_valid():
                try:
                    # 保存表单数据
                    complaint_instance = form.save()
                except Exception as e:
                    return Response({'code': 500, 'message': '表单保存失败', 'error': str(e)})

                if images:
                    try:
                        for image_file in images:
                            print(1)
                            # 直接将文件对象传递给 ImageField，文件名由 upload_to 函数处理
                            complaint_media = ComplaintMedia(comp_media=image_file, comp_list=complaint_instance)
                            complaint_media.save()
                    except Exception as e:
                        return Response({'code': 500, 'message': '图片保存失败', 'error': str(e)})

                    return Response({'code': 200, 'message': '提交图片和表单成功'})
                else:
                    return Response({'code': 200, 'data': form.data, 'message': '提交成功'})
            else:
                return Response({'code': 400, 'message': form.errors})
        else:
            return Response(login_status)


class ComplaintWhich(APIView):
    def get(self, request, pk):
        token = request.headers.get('Authorization')
        login_status = is_login_user(token)  # 用户使用某个表单查询
        if login_status['code'] == 200:
            try:
                obj = Complaint.objects.filter(pk=pk).prefetch_related('complaintmedia_set').all()
                ser = ComplaintSerializer(instance=obj, many=True, context={'request': request})
            except Exception as e:
                return Response({'code': 500, "message": '用户具体表单获取数据出错', "error": str(e)})
            return Response({'code': 200, 'data': ser.data, 'message': '获取列表成功'})
        else:
            return Response(login_status)

    def put(self, request, pk):  # 用户进行评价的函数
        token = request.headers.get('Authorization')
        login_status = is_login_user(token)
        if login_status['code'] == 200:
            try:
                data = json.loads(request.body)
                feedback = data.get('comp_feedback', None)
            except Exception as e:
                return Response({'code': 500, "message": '提交修改数据格式出错', "error": str(e)})
            if feedback is not None:
                try:
                    obj = Complaint.objects.get(pk=pk)
                    obj.comp_feedback = feedback
                    obj.save()
                except Exception as e:
                    return Response({'code': 500, "message": '用户反馈数据保存失败', "error": str(e)})
                return Response({'code': 200, 'data': feedback, 'message': '评价成功！'})
            else:
                return Response({'code': 400, 'message': '评价错误'})
        else:
            return Response(login_status)


class ComplaintUserDetail(APIView):  # 用户获取detail
    def get(self, request):
        token = request.headers.get('Authorization')
        login_status = is_login_user(token)
        if login_status['code'] == 200:
            try:
                result = verify_token(token)
                aa = result['data']
                user_id = aa['id']
                obj = Complaint.objects.filter(comp_sub_id=user_id).prefetch_related('complaintmedia_set').all()
            except Exception as e:
                return Response({'code': 500, "message": '用户投诉表数据获取出错', "error": str(e)})
            if obj:  # 改了下，处理了下用户未提交任何投诉表的问题
                ser = ComplaintSerializer(instance=obj, many=True)
                return Response({'code': 200, 'data': ser.data, 'message': '查询到用户的所有投诉'})
            else:
                return Response({'code': 404, 'message': '该用户未提交任何投诉'})
        else:
            return Response(login_status)


class ManagerHistory(APIView):
    def get(self, request):
        token = request.headers.get('Authorization')
        login_status = is_login_manager(token)
        if login_status['code'] == 200:
            result = verify_token(token)
            aa = result['data']
            manager_id = aa['id']
            try:
                obj1 = Suggestion.objects.filter(
                    Q(sugg_handle_id=manager_id, sugg_status=True, sugg_treat=0) | Q(sugg_handle_id=manager_id,
                                                                                     sugg_treat=2)).prefetch_related(
                    'suggestionmedia_set').all()
                ser1 = SuggestionSerializer(instance=obj1, many=True, context={'request': request})
                obj2 = Complaint.objects.filter(
                    Q(comp_handle_id=manager_id, comp_status=True, comp_treat=0) | Q(comp_handle_id=manager_id,
                                                                                     comp_treat=2)).prefetch_related(
                    'complaintmedia_set').all()
                ser2 = ComplaintSerializer(instance=obj2, many=True, context={'request': request})
            except Exception as e:
                return Response({'code': 500, "message": '获取所有历史记录出错', "error": str(e)})
            return Response({
                'code': 200,
                'data': {
                    'suggestions': ser1.data,
                    'complaints': ser2.data
                },
                'message': '获取历史记录成功'
            })
        else:
            return Response(login_status)


class ComplaintHistory(APIView):
    def get(self, request):
        token = request.headers.get('Authorization')
        login_status = is_login_manager(token)
        if login_status['code'] == 200:
            result = verify_token(token)
            aa = result['data']
            manager_id = aa['id']
            try:
                try:
                    # 获取前端分页参数
                    pagenum = int(request.GET.get('pagenum'))  # 当前页码，默认为第1页
                    pagesize = int(request.GET.get('pagesize'))  # 每页条数，默认为10条
                except ValueError:
                    return Response({'code': 400, 'message': '分页参数无效'}, status=400)
                params = Complaint.objects.filter(
                    Q(comp_handle_id=manager_id, comp_status=True, comp_treat=0) | Q(comp_handle_id=manager_id,
                                                                                     comp_treat=2)).order_by('-id')
                # 使用 Paginator 进行分页
                paginator = Paginator(params, pagesize)
                try:
                    # 获取当前页的数据
                    page_data = paginator.page(pagenum)
                except Exception as e:
                    return Response({'code': 500, 'message': f'分页出错: {str(e)}'}, status=500)
                if page_data:
                    ser = ComplaintSerializer_list(instance=page_data, many=True)
                    # 构造分页返回结果
                    result = {
                        'code': 200,
                        'data': ser.data,
                        'message': '获取未处理表单成功',
                        'total': paginator.count,  # 数据总条数
                        'total_pages': paginator.num_pages,  # 总页数
                        'pagenum': pagenum,  # 当前页码
                        'pagesize': pagesize,  # 每页条数
                    }
                    return Response(result)
                else:
                    return Response({'code': 404, 'message': "未找到表单！"})
            except Exception as e:
                return Response({'code': 500, "message": '获取所有历史记录出错', "error": str(e)})
        else:
            return Response(login_status)


class ComplaintHistoryWhich(APIView):
    def get(self, request, pk):
        token = request.headers.get('Authorization')
        login_status = is_login_manager(token)
        if login_status['code'] == 200:
            try:
                obj2 = Complaint.objects.filter(pk=pk).prefetch_related('complaintmedia_set',
                                                                        'complainthandlemedia_set').all()
                ser2 = ComplaintSerializer(instance=obj2, many=True)
            except Exception as e:
                return Response({'code': 500, "message": '获取所有历史记录出错', "error": str(e)})
            return Response({
                'code': 200,
                'data': ser2.data,
                'message': '获取历史记录成功'
            })
        else:
            return Response(login_status)


class SuggestionHistory(APIView):
    def get(self, request):
        token = request.headers.get('Authorization')
        login_status = is_login_manager(token)
        if login_status['code'] == 200:
            result = verify_token(token)
            aa = result['data']
            manager_id = aa['id']
            try:
                try:
                    # 获取前端分页参数
                    pagenum = int(request.GET.get('pagenum'))  # 当前页码，默认为第1页
                    pagesize = int(request.GET.get('pagesize'))  # 每页条数，默认为10条
                except ValueError:
                    return Response({'code': 400, 'message': '分页参数无效'}, status=400)
                params = Suggestion.objects.filter(
                    Q(sugg_handle_id=manager_id, sugg_status=True, sugg_treat=0) | Q(sugg_handle_id=manager_id,
                                                                                     sugg_treat=2)).order_by('-id')
                print(params)
                # 使用 Paginator 进行分页
                paginator = Paginator(params, pagesize)
                try:
                    # 获取当前页的数据
                    page_data = paginator.page(pagenum)
                except Exception as e:
                    return Response({'code': 500, 'message': f'分页出错: {str(e)}'}, status=500)
                if page_data:
                    ser = SuggestionSerializer_list(instance=page_data, many=True)
                    # 构造分页返回结果
                    result = {
                        'code': 200,
                        'data': ser.data,
                        'message': '获取未处理表单成功',
                        'total': paginator.count,  # 数据总条数
                        'total_pages': paginator.num_pages,  # 总页数
                        'pagenum': pagenum,  # 当前页码
                        'pagesize': pagesize,  # 每页条数
                    }
                    return Response(result)
                else:
                    return Response({'code': 404, 'message': "未找到未处理表单"})
            except Exception as e:
                return Response({'code': 500, "message": '获取所有历史记录出错', "error": str(e)})
        else:
            return Response(login_status)


class SuggestionHistoryWhich(APIView):
    def get(self, request, pk):
        token = request.headers.get('Authorization')
        login_status = is_login_manager(token)
        if login_status['code'] == 200:
            try:
                obj2 = Suggestion.objects.filter(pk=pk).prefetch_related('suggestionmedia_set',
                                                                         'suggestionhandlemedia_set').all()
                ser2 = SuggestionSerializer(instance=obj2, many=True)
            except Exception as e:
                return Response({'code': 500, "message": '获取所有历史记录出错', "error": str(e)})
            return Response({
                'code': 200,
                'data': ser2.data,
                'message': '获取历史记录成功'
            })
        else:
            return Response(login_status)


class UserDetailAll(APIView):
    def get(self, request):
        token = request.headers.get('Authorization')
        login_status = is_login_user(token)
        if login_status['code'] == 200:
            result = verify_token(token)
            aa = result['data']
            user_id = aa['id']
            try:
                obj1 = Suggestion.objects.filter(sugg_sub_id=user_id, sugg_status=True).prefetch_related(
                    'suggestionmedia_set').all()
                ser1 = SuggestionSerializerUserAll(instance=obj1, many=True, context={'request': request})
                obj2 = Complaint.objects.filter(comp_sub_id=user_id, comp_status=True).prefetch_related(
                    'complaintmedia_set').all()
                ser2 = ComplaintSerializerUserAll(instance=obj2, many=True, context={'request': request})
            except Exception as e:
                return Response({'code': 500, "message": '获取用户所有表单出错', "error": str(e)})
            return Response({
                'code': 200,
                'data': ser1.data + ser2.data,
                'message': '获取用户所有表单成功'
            })
        else:
            return Response(login_status)


class UserFreq(APIView):
    def post(self, request):
        token = request.headers.get('Authorization')
        login_status = is_login_user(token)
        if login_status['code'] == 200:
            result = verify_token(token)
            aa = result['data']
            user_id = aa['id']
            try:
                freqs = User.objects.filter(id=user_id).first()
                freq = freqs.user_freq + 1
                User.objects.filter(id=user_id).update(user_freq=freq)
            except Exception as e:
                return Response({'code': 500, "message": '用户修改访问量出错', "error": str(e)})
            return Response({'code': 200, 'message': '修改访问次数'})
        else:
            return Response(login_status)


class UserView(APIView):  # 因为先创建用户，所以这里应该是修改
    def put(self, request):
        token = request.headers.get('Authorization')
        login_status = is_login_user(token)
        if login_status['code'] == 200:
            result = verify_token(token)
            aa = result['data']
            user_id = aa['id']
            try:
                json_data = request.data
                user_image = request.FILES.get('user_image')
                user_info = json_data.get('user_info')
                user_nick = json_data.get('user_nick')
                user_address = json_data.get('user_address')
                user_tele = json_data.get('user_tele')
            except Exception as e:
                return Response({'code': 500, "message": '用户数据出错', "error": str(e)})

            if user_tele:
                try:
                    User.objects.filter(id=user_id).update(user_tele=user_tele)
                except Exception as e:
                    return Response({'code': 500, "message": '用户修改电话出错', "error": str(e)})
                return Response({'code': 200, "message": '修改电话成功'})
            elif user_info:
                try:
                    User.objects.filter(id=user_id).update(user_info=user_info)
                except Exception as e:
                    return Response({'code': 500, "message": '用户修改简介出错', "error": str(e)})
                return Response({'code': 200, "message": '修改简介成功'})
            elif user_nick:
                try:
                    User.objects.filter(id=user_id).update(user_nick=user_nick)
                except Exception as e:
                    return Response({'code': 500, "message": '用户修改昵称出错', "error": str(e)})
                return Response({'code': 200, "message": '修改昵称成功'})
            elif user_address:
                try:
                    user_address = user_address[0]  # 这里要测试
                    User.objects.filter(id=user_id).update(user_address=user_address)
                except Exception as e:
                    return Response({'code': 500, "message": '用户修改地址出错', "error": str(e)})
                return Response({'code': 200, "message": '修改地址成功'})
            elif user_image:
                try:
                    obj = User.objects.get(id=user_id)
                    obj.user_image = user_image
                    obj.save()
                except Exception as e:
                    return Response({'code': 500, "message": '修改图像错误', "error": str(e)})
                return Response({'code': 200, 'message': '修改用户图片成功'})
            else:
                return Response({'code': 200, 'message': '未进行修改'})
        else:
            return Response(login_status)

    def get(self, request):
        token = request.headers.get('Authorization')
        login_status = is_login_user(token)
        if login_status['code'] == 200:
            result = verify_token(token)
            aa = result['data']
            user_id = aa['id']
            users = User.objects.filter(pk=user_id)
            if not users:
                return Response({'code': 200, 'message': '用户不存在'})
            else:
                ser = UserSerializer(instance=users, many=True)
                return Response({'code': 200, 'data': ser.data, 'message': '获取用户成功'})
        else:
            return Response(login_status)


class WarnView(APIView):
    def post(self, request):
        token = request.headers.get('Authorization')
        login_status = is_login_manager(token)
        if login_status['code'] == 200:
            ser = WarnSerializer(data=request.data)
            if ser.is_valid():
                try:
                    Warn.objects.create(**ser.validated_data)
                except Exception as e:
                    return Response({'code': 500, "message": '增加温馨提示失败', "error": str(e)})
                return Response({'code': 200, "message": '上传成功'})
            else:
                return Response({'code': 400, "message": '数据格式错误', "data": ser.errors})
        else:
            return Response(login_status)

    def get(self, request):  # 管理员获取
        token = request.headers.get('Authorization')
        login_status = is_login_manager(token)
        if login_status['code'] == 200:
            try:
                warn_obj = Warn.objects.last()
            except Exception as e:
                return Response({'code': 500, "message": '获取热线数据失败', "error": str(e)})
            ser = WarnSerializer(instance=warn_obj, many=False)
            return Response({"code": 200, "data": ser.data})
        else:
            return Response(login_status)


class WarnViewUser(APIView):
    def get(self, request):  # 用户
        token = request.headers.get('Authorization')
        login_status = is_login_user(token)
        if login_status['code'] == 200:
            try:
                warn_obj = Warn.objects.last()
            except Exception as e:
                return Response({'code': 500, "message": '获取热线数据失败', "error": str(e)})
            ser = WarnSerializer(instance=warn_obj, many=False)
            return Response({"code": 200, "data": ser.data})
        else:
            return Response(login_status)


class HotlineView(APIView):
    def post(self, request):
        token = request.headers.get('Authorization')
        login_status = is_login_manager(token)
        if login_status['code'] == 200:
            ser = HotlineSerializer(data=request.data)
            if ser.is_valid():
                try:
                    Hotline.objects.create(**ser.validated_data)
                except Exception as e:
                    return Response({'code': 500, "message": '增加热线失败', "error": str(e)})
                return Response({'code': 200, "message": '上传成功'})
            else:
                return Response({'code': 400, "message": '数据格式错误', "data": ser.errors})
        else:
            return Response(login_status)

    def get(self, request):
        token = request.headers.get('Authorization')
        login_status_manager = is_login_manager(token)
        if login_status_manager['code'] == 200:
            try:
                hotline_obj = Hotline.objects.all()
            except Exception as e:
                return Response({'code': 500, "message": '获取热线数据失败', "error": str(e)})
            if hotline_obj:
                ser = HotlineSerializer(instance=hotline_obj, many=True)
                return Response({"code": 200, "data": ser.data})
            else:
                return Response({"code": 404, "message": '未查询到'})
        else:
            return Response(login_status_manager)


class HotlineUser(APIView):
    def get(self, request):  # 这里的get为用户查询
        # token = request.headers.get('Authorization')
        # login_status = is_login_user(token)
        # if login_status['code'] == 200:
        try:
            params = Hotline.objects.all()
        except Exception as e:
            return Response({'code': 500, "message": '获取热线失败', "error": str(e)})
        if params:  # 改了下,现在是如果params为空的话，会返回状态码400(验证过了)
            ser = HotlineSerializer(instance=params, many=True)
            return Response({'code': 200, 'data': ser.data, 'message': '获取所有热线信息'})
        else:
            return Response({'code': 404, 'message': '无热线信息'})
    # else:
    #     return Response(login_status)


class HotlineDetailView(APIView):
    def put(self, request, pk):
        token = request.headers.get('Authorization')
        login_status = is_login_manager(token)
        if login_status['code'] == 200:
            ser = HotlineSerializer(data=request.data)
            if ser.is_valid():
                try:
                    Hotline.objects.filter(pk=pk).update(**ser.validated_data)
                except Exception as e:
                    return Response({'code': 500, "message": '修改热线失败', "error": str(e)})
                return Response({'code': 200, "message": '修改成功'})
            else:
                return Response({'code': 400, "message": '数据格式错误', "data": ser.errors})
        else:
            return Response(login_status)

    def delete(self, request, pk):
        token = request.headers.get('Authorization')
        login_status = is_login_manager(token)
        if login_status['code'] == 200:
            try:
                Hotline.objects.filter(pk=pk).delete()
                return Response({'code': 200, "message": '删除成功'})
            except Exception as e:
                return Response({'code': 404, "message": '删除失败', "error": str(e)})
        else:
            return Response(login_status)


class CoverView(APIView):
    def post(self, request):
        token = request.headers.get('Authorization')
        login_status = is_login_manager(token)
        if login_status['code'] == 200:
            cover_file = request.FILES.get('cover_file')
            if cover_file:
                try:
                    cover_media = Cover(cover_file=cover_file)
                    cover_media.save()
                    return Response({'code': 200, 'message': '图片保存成功！'})
                except Exception as e:
                    return Response({'code': 500, 'message': '图片保存失败', 'error': str(e)})
        else:
            return Response(login_status)

    def get(self, request):  # 只有管理员
        token = request.headers.get('Authorization')
        login_status_manager = is_login_manager(token)
        if login_status_manager['code'] == 200:
            obj = Cover.objects.all()
            if obj:
                ser = CoverSerializer(instance=obj, many=True)
                return Response({'code': 200, 'data': ser.data, 'message': '获取封面成功'})
            else:
                return Response({"code": 404, "message": '未找到相关图片'})
        else:
            return Response(login_status_manager)


class CoverViewUser(APIView):
    def get(self, request):
        # token = request.headers.get('Authorization')
        # login_status_user = is_login_user(token)
        # if login_status_user['code'] == 200:
        obj = Cover.objects.all()
        if obj:
            ser = CoverSerializer(instance=obj, many=True)
            return Response({'code': 200, 'data': ser.data, 'message': '获取轮播图成功'})
        else:
            return Response({"code": 404, "message": '未找到相关图片'})
    # else:
    #     return Response(login_status_user)


class CoverDetailView(APIView):
    def delete(self, request, pk):
        token = request.headers.get('Authorization')
        login_status = is_login_manager(token)
        if login_status['code'] == 200:
            try:
                Cover.objects.filter(pk=pk).delete()
                return Response({'code': 200, "message": '删除成功'})
            except Exception as e:
                return Response({'code': 500, "message": '删除失败', "error": str(e)})
        else:
            return Response(login_status)

    def put(self, request, pk):
        token = request.headers.get('Authorization')
        login_status = is_login_manager(token)
        if login_status['code'] == 200:
            cover_file = request.FILES.get('cover_file')
            if not cover_file:
                return JsonResponse({'code': 400, "message": '封面修改失败'})
            else:
                try:
                    Cover.objects.filter(pk=pk).update(cover_file=cover_file)
                    return Response({'code': 200, "message": '修改成功'})
                except Exception as e:
                    return Response({'code': 500, "message": '封面更新失败', "error": str(e)})
        else:
            return Response(login_status)


class FrequencyView(APIView):  # manager的函数
    def get(self, request):
        token = request.headers.get('Authorization')
        login_status = is_login_manager(token)
        if login_status['code'] == 200:
            try:
                obj = User.objects.all().values('user_freq')
                total_sum = sum(item['user_freq'] for item in obj)  # 可以实现把User中所有对象的user_freq取出，并加和的功能
                return Response({'code': 200, 'data': total_sum, 'message': '获取总访问量成功'})
            except Exception as e:
                return Response({'code': 500, "message": '获取总量失败', "error": str(e)})
        else:
            return Response(login_status)


class BackgroundView(APIView):
    def post(self, request):
        token = request.headers.get('Authorization')
        login_status = is_login_manager(token)

        if login_status['code'] == 200:
            back_file = request.FILES.get('back_file')
            if not back_file:
                return JsonResponse({'code': 400, "message": '封面上传失败'})
            else:
                try:
                    # 删除所有现有的图片记录
                    Background.objects.all().delete()

                    # 创建新的图片记录
                    Background.objects.create(back_file=back_file)

                    return Response({'code': 200, "message": '上传成功'})
                except Exception as e:
                    return Response({'code': 500, "message": '上传失败', "error": str(e)})
        else:
            return Response(login_status)

    def get(self, request):
        obj = Background.objects.all()
        if obj:
            ser = BackSerializer(instance=obj, many=True)
            return Response({'code': 200, 'data': ser.data, 'message': '获取封面成功'})
        else:
            return Response({'code': 404, 'message': '未找到相关图片'})


from datetime import timedelta
import pytz

flag = 5


class GetExcelNew(APIView):
    def post(self, request):
        global flag
        token = request.headers.get('Authorization')
        login_status = is_login_manager(token)
        if login_status['code'] == 200:
            try:
                json_data = json.loads(request.body)
                time1 = json_data.get('start_time')
                time2 = json_data.get('finish_time')
            except Exception as e:
                response_content = {
                    'message': '时间格式出错',
                    'errors': str(e)
                }
                return JsonResponse(response_content, status=201)

            # 解析 request 中的 naive 时间
            try:
                naive_time1 = dt.strptime(time1, '%Y-%m-%d')
                naive_time2 = dt.strptime(time2, '%Y-%m-%d')
            except Exception as e:
                response_content = {
                    'message': '时间格式出错',
                    'errors': str(e)
                }
                return JsonResponse(response_content, status=201)

            # 将 naive 时间本地化到东八区
            try:
                tz = pytz.timezone('Asia/Shanghai')
                time1_with_tz = tz.localize(naive_time1)
                time2_with_tz = tz.localize(naive_time2)
                # 仅用于查询
                start_time = time1_with_tz.strftime('%Y-%m-%d-%H')
                finish_time = time2_with_tz.strftime('%Y-%m-%d-%H')
            except Exception as e:
                response_content = {
                    'message': '时间格式出错',
                    'errors': str(e)
                }
                return JsonResponse(response_content, status=201)

            if start_time == finish_time:
                try:
                    obj1 = Complaint.objects.filter(comp_sub_time__date=time1_with_tz.date())
                    obj2 = Suggestion.objects.filter(sugg_sub_time__date=time1_with_tz.date())
                    if obj1 and obj2:
                        pass
                    elif not obj1 and not obj2:
                        response_content = {
                            'message': '未找到时间范围内的表单',
                        }
                        return JsonResponse(response_content, status=201)
                    elif not obj1 and obj2:
                        flag = 1  # 没投诉有建议
                    elif obj1 and not obj2:
                        flag = 2  # 有投诉没建议
                except Exception as e:
                    response_content = {
                        'message': '时间格式出错',
                        'errors': str(e)
                    }
                    return JsonResponse(response_content, status=201)
            else:
                try:
                    obj1 = Complaint.objects.filter(comp_sub_time__range=(time1_with_tz, time2_with_tz))
                    obj2 = Suggestion.objects.filter(sugg_sub_time__range=(time1_with_tz, time2_with_tz))
                    if obj1 and obj2:
                        flag = 0
                    elif not obj1 and not obj2:
                        response_content = {
                            'message': '未找到时间范围内的表单',
                        }
                        return JsonResponse(response_content, status=201)
                    elif not obj1 and obj2:
                        flag = 1  # 没投诉有建议
                    elif obj1 and not obj2:
                        flag = 2  # 有投诉没建议
                except Exception as e:
                    response_content = {
                        'message': '时间格式出错',
                        'errors': str(e)
                    }
                    return JsonResponse(response_content, status=201)
            if flag == 2:
                try:
                    obj1_list = list(obj1.values(
                        'comp_id', 'comp_name', 'comp_title', 'comp_user_tele', 'comp_text', 'comp_site',
                        'comp_sub_time', 'comp_status', 'comp_staff_name', 'comp_content',
                        'comp_way', 'comp_handle_time', 'comp_staff_tele', 'comp_treat', 'comp_feedback',
                        'comp_summary'
                    ))
                    obj2_list = [{' ': ' '}]
                    df = pd.DataFrame(obj1_list)
                    df2 = pd.DataFrame(obj2_list)
                except Exception as e:
                    response_content = {
                        'message': '下载excel出错',
                        'errors': str(e)
                    }
                    return JsonResponse(response_content, status=201)

                try:
                    status_mapping = {
                        False: '未处理',
                        True: '已处理'
                    }
                    # 应用状态映射
                    df['comp_status'] = df['comp_status'].replace(status_mapping)
                    treat_mapping = {
                        0: '不需要回访',
                        1: '暂未回访',
                        2: '已回访'
                    }
                    df['comp_treat'] = df['comp_treat'].replace(treat_mapping)
                    feedback_mapping = {
                        0: '',
                        1: '非常满意',
                        2: '满意',
                        3: '基本满意',
                        4: '一般',
                        5: '不满意',
                    }
                    df['comp_feedback'] = df['comp_feedback'].replace(feedback_mapping)
                except Exception as e:
                    response_content = {
                        'message': '下载excel出错',
                        'errors': str(e)
                    }
                    return JsonResponse(response_content, status=201)

                def format_date(datetime_obj):
                    # 确保 datetime_obj 是带时区信息的 datetime 对象
                    try:
                        # 使用 pandas 的 to_datetime 保留时区信息
                        datetime_with_tz = pd.to_datetime(datetime_obj, utc=True).tz_convert('Asia/Shanghai')
                    except Exception as e11:
                        response_content22 = {
                            'message': '下载excel出错',
                            'errors': str(e11)
                        }
                        return JsonResponse(response_content22, status=201)
                    # 按指定格式输出时间，包括时区信息
                    return datetime_with_tz.strftime('%Y年%m月%d日%H时')

                def process_handle_time(row):
                    # 如果 comp_status 为 False，则处理时间改为 "暂未处理"
                    if row['comp_status'] == '未处理':
                        return "暂未处理"
                    else:
                        return format_date(row['comp_handle_time'])

                try:
                    df['comp_sub_time'] = df['comp_sub_time'].apply(format_date)
                    df['comp_handle_time'] = df['comp_handle_time'].apply(process_handle_time)
                    df.columns = ['编号', '投诉人姓名', '投诉标题', '投诉人电话', '投诉内容', '投诉地点', '投诉时间',
                                  '处理状态',
                                  '处理人姓名', '处理内容', '处理方式', '处理时间', '处理人电话', '是否需要回访',
                                  '居民反馈评价', '回访总结']
                    df2.columns = ['建议表为空']
                except Exception as e:
                    response_content = {
                        'message': '下载excel出错',
                        'errors': str(e)
                    }
                    return JsonResponse(response_content, status=201)

                # 设置工作文件夹路径
                work_folder = '/room/docker_media/files/'

                # 确保工作文件夹存在
                try:
                    if not os.path.exists(work_folder):
                        print("路径")
                        os.makedirs(work_folder)
                except Exception as e:
                    response_content = {
                        'message': '下载excel出错',
                        'errors': str(e)
                    }
                    return JsonResponse(response_content, status=201)

                # 设置Excel文件名
                try:
                    print("创建路径")
                    timestamp = dt.now().strftime('%Y%m%d_%H%M%S')
                    excel_filename = f'投诉记录_{timestamp}.xlsx'
                    excel_filepath = os.path.join(work_folder, excel_filename)
                    # 将DataFrame保存为Excel文件
                    with pd.ExcelWriter(excel_filepath) as writer:
                        df.to_excel(writer, sheet_name='居民诉求', index=False)
                        df2.to_excel(writer, sheet_name='居民建议', index=False)

                    print(f"Excel file generated at: {excel_filepath}")
                    # 确保文件确实存在
                    if not os.path.isfile(excel_filepath):
                        raise FileNotFoundError(f"File not found at path: {excel_filepath}")
                    # 读取文件并提供下载
                    file = open(excel_filepath, 'rb')
                    response = FileResponse(file)
                    # 使用生成的Excel文件名作为返回的文件名
                    response['Content-Disposition'] = f'attachment; filename="{excel_filename}"'
                    return response
                except Exception as e:
                    response_content = {
                        'message': '下载excel出错',
                        'errors': str(e)
                    }
                    return JsonResponse(response_content, status=201)
            elif flag == 1:
                try:
                    obj1_list = [{' ': ' '}]
                    obj2_list = list(obj2.values(
                        'sugg_id', 'sugg_name', 'sugg_title', 'sugg_user_tele', 'sugg_text', 'sugg_site',
                        'sugg_sub_time', 'sugg_status', 'sugg_staff_name', 'sugg_content',
                        'sugg_way', 'sugg_handle_time', 'sugg_staff_tele', 'sugg_treat', 'sugg_feedback',
                        'sugg_summary'
                    ))
                    df = pd.DataFrame(obj1_list)
                    df2 = pd.DataFrame(obj2_list)
                except Exception as e:
                    response_content = {
                        'message': '下载excel出错',
                        'errors': str(e)
                    }
                    return JsonResponse(response_content, status=201)

                try:
                    status_mapping = {
                        False: '未处理',
                        True: '已处理'
                    }
                    # 应用状态映射
                    df2['sugg_status'] = df2['sugg_status'].replace(status_mapping)
                    treat_mapping = {
                        0: '不需要回访',
                        1: '暂未回访',
                        2: '已回访'
                    }
                    df2['sugg_treat'] = df2['sugg_treat'].replace(treat_mapping)
                    feedback_mapping = {
                        0: '',
                        1: '非常满意',
                        2: '满意',
                        3: '基本满意',
                        4: '一般',
                        5: '不满意',
                    }
                    df2['comp_feedback'] = df2['comp_feedback'].replace(feedback_mapping)
                except Exception as e:
                    response_content = {
                        'message': '下载excel出错',
                        'errors': str(e)
                    }
                    return JsonResponse(response_content, status=201)

                def format_date(datetime_obj):
                    # 确保 datetime_obj 是带时区信息的 datetime 对象
                    try:
                        # 使用 pandas 的 to_datetime 保留时区信息
                        datetime_with_tz = pd.to_datetime(datetime_obj, utc=True).tz_convert('Asia/Shanghai')
                    except Exception as e1:
                        response_content11 = {
                            'message': '下载excel出错',
                            'errors': str(e1)
                        }
                        return JsonResponse(response_content11, status=201)
                    # 按指定格式输出时间，包括时区信息
                    return datetime_with_tz.strftime('%Y年%m月%d日%H时')

                def process_handle_time(row):
                    # 如果 comp_status 为 False，则处理时间改为 "暂未处理"
                    if row['sugg_status'] == '未处理':
                        return "暂未处理"
                    else:
                        return format_date(row['sugg_handle_time'])

                try:
                    df['sugg_sub_time'] = df['sugg_sub_time'].apply(format_date)
                    df['sugg_handle_time'] = df['sugg_handle_time'].apply(process_handle_time)
                    df2.columns = ['编号', '建议人姓名', '建议标题', '建议人电话', '建议内容', '建议地点', '建议时间',
                                   '处理状态',
                                   '处理人姓名',
                                   '处理内容', '处理方式', '处理时间', '处理人电话', '是否需要回访',
                                   '居民反馈评价', '回访总结']
                    df.columns = ['投诉表为空']
                except Exception as e:
                    response_content = {
                        'message': '下载excel出错',
                        'errors': str(e)
                    }
                    return JsonResponse(response_content, status=201)

                # 设置工作文件夹路径
                work_folder = '/room/docker_media/files/'

                # 确保工作文件夹存在
                try:
                    if not os.path.exists(work_folder):
                        print("路径")
                        os.makedirs(work_folder)
                except Exception as e:
                    response_content = {
                        'message': '下载excel出错',
                        'errors': str(e)
                    }
                    return JsonResponse(response_content, status=201)

                # 设置Excel文件名
                try:
                    timestamp = dt.now().strftime('%Y%m%d_%H%M%S')
                    excel_filename = f'建议记录_{timestamp}.xlsx'
                    excel_filepath = os.path.join(work_folder, excel_filename)
                    # 将DataFrame保存为Excel文件
                    with pd.ExcelWriter(excel_filepath) as writer:
                        df2.to_excel(writer, sheet_name='居民建议', index=False)
                        df.to_excel(writer, sheet_name='居民投诉', index=False)
                    # 确保文件确实存在
                    if not os.path.isfile(excel_filepath):
                        raise FileNotFoundError(f"File not found at path: {excel_filepath}")
                    # 读取文件并提供下载
                    file = open(excel_filepath, 'rb')
                    response = FileResponse(file)
                    # 使用生成的Excel文件名作为返回的文件名
                    response['Content-Disposition'] = f'attachment; filename="{excel_filename}"'
                    return response
                except Exception as e:
                    response_content = {
                        'message': '下载excel出错',
                        'errors': str(e)
                    }
                    return JsonResponse(response_content, status=201)
            elif flag == 0:
                try:
                    obj1_list = list(obj1.values(
                        'comp_id', 'comp_name', 'comp_title', 'comp_user_tele', 'comp_text', 'comp_site',
                        'comp_sub_time', 'comp_status', 'comp_staff_name', 'comp_content',
                        'comp_way', 'comp_handle_time', 'comp_staff_tele', 'comp_treat', 'comp_feedback',
                        'comp_summary'
                    ))
                    obj2_list = list(obj2.values(
                        'sugg_id', 'sugg_name', 'sugg_title', 'sugg_user_tele', 'sugg_text', 'sugg_site',
                        'sugg_sub_time', 'sugg_status', 'sugg_staff_name', 'sugg_content',
                        'sugg_way', 'sugg_handle_time', 'sugg_staff_tele', 'sugg_treat', 'sugg_feedback',
                        'sugg_summary'
                    ))
                    df = pd.DataFrame(obj1_list)
                    df2 = pd.DataFrame(obj2_list)
                except Exception as e:
                    response_content = {
                        'message': '下载excel出错',
                        'errors': str(e)
                    }
                    return JsonResponse(response_content, status=201)

                try:
                    status_mapping = {
                        False: '未处理',
                        True: '已处理'
                    }
                    # 应用状态映射
                    df['comp_status'] = df['comp_status'].replace(status_mapping)
                    df2['sugg_status'] = df2['sugg_status'].replace(status_mapping)
                    treat_mapping = {
                        0: '不需要回访',
                        1: '暂未回访',
                        2: '已回访'
                    }
                    df['comp_treat'] = df['comp_treat'].replace(treat_mapping)
                    df2['sugg_treat'] = df2['sugg_treat'].replace(treat_mapping)
                    feedback_mapping = {
                        0: '',
                        1: '非常满意',
                        2: '满意',
                        3: '基本满意',
                        4: '一般',
                        5: '不满意',
                    }
                    df['comp_feedback'] = df['comp_feedback'].replace(feedback_mapping)
                    df2['sugg_feedback'] = df2['sugg_feedback'].replace(feedback_mapping)
                except Exception as e:
                    response_content = {
                        'message': '下载excel出错',
                        'errors': str(e)
                    }
                    return JsonResponse(response_content, status=201)

                def format_date(datetime_obj):
                    # 确保 datetime_obj 是带时区信息的 datetime 对象
                    try:
                        # 使用 pandas 的 to_datetime 保留时区信息
                        datetime_with_tz = pd.to_datetime(datetime_obj, utc=True).tz_convert('Asia/Shanghai')
                    except Exception as e1:
                        response_content1 = {
                            'message': '下载excel出错',
                            'errors': str(e1)
                        }
                        return JsonResponse(response_content1, status=201)
                    # 按指定格式输出时间，包括时区信息
                    return datetime_with_tz.strftime('%Y年%m月%d日%H时')

                def process_handle_time1(row):
                    # 如果 comp_status 为 False，则处理时间改为 "暂未处理"
                    if row['comp_status'] == '未处理':
                        return "暂未处理"
                    else:
                        return format_date(row['comp_handle_time'])

                def process_handle_time2(row):
                    # 如果 comp_status 为 False，则处理时间改为 "暂未处理"
                    if row['sugg_status'] == '未处理':
                        return "暂未处理"
                    else:
                        return format_date(row['sugg_handle_time'])

                try:
                    df['comp_sub_time'] = df['comp_sub_time'].apply(format_date)
                    df['comp_handle_time'] = df.apply(process_handle_time1, axis=1)
                    df.columns = ['编号', '投诉人姓名', '投诉标题', '投诉人电话', '投诉内容', '投诉地点', '投诉时间',
                                  '处理状态',
                                  '处理人姓名', '处理内容', '处理方式', '处理时间', '处理人电话', '是否需要回访',
                                  '居民反馈评价', '回访总结']
                    df2['sugg_sub_time'] = df2['sugg_sub_time'].apply(format_date)
                    df2['sugg_handle_time'] = df2.apply(process_handle_time2, axis=1)
                    df2.columns = ['编号', '建议人姓名', '建议标题', '建议人电话', '建议内容', '建议地点', '建议时间',
                                   '处理状态',
                                   '处理人姓名', '处理内容', '处理方式', '处理时间', '处理人电话', '是否需要回访',
                                   '居民反馈评价', '回访总结']
                except Exception as e:
                    response_content = {
                        'message': '下载excel出错1',
                        'errors': str(e)
                    }
                    return JsonResponse(response_content, status=201)

                # 设置工作文件夹路径
                work_folder = '/room/docker_media/files/'

                # 确保工作文件夹存在
                try:
                    if not os.path.exists(work_folder):
                        os.makedirs(work_folder)
                except Exception as e:
                    response_content = {
                        'message': '下载excel出错',
                        'errors': str(e)
                    }
                    return JsonResponse(response_content, status=201)

                # 设置Excel文件名
                try:
                    timestamp = dt.now().strftime('%Y%m%d_%H%M%S')
                    excel_filename = f'建议投诉记录_{timestamp}.xlsx'
                    excel_filepath = os.path.join(work_folder, excel_filename)
                    # 将DataFrame保存为Excel文件
                    with pd.ExcelWriter(excel_filepath) as writer:
                        df.to_excel(writer, sheet_name='居民诉求', index=False)
                        df2.to_excel(writer, sheet_name='居民建议', index=False)

                    print(f"Excel file generated at: {excel_filepath}")
                    # 确保文件确实存在
                    if not os.path.isfile(excel_filepath):
                        raise FileNotFoundError(f"File not found at path: {excel_filepath}")
                    # 读取文件并提供下载
                    file = open(excel_filepath, 'rb')
                    response = FileResponse(file)
                    # 使用生成的Excel文件名作为返回的文件名
                    response['Content-Disposition'] = f'attachment; filename="{excel_filename}"'
                    return response
                except Exception as e:
                    response_content = {
                        'message': '下载excel出错',
                        'errors': str(e)
                    }
                    return JsonResponse(response_content, status=201)
            else:
                response_content = {
                    'message': "选定时间内无投诉和建议表"
                }
                return JsonResponse(response_content, status=201)
        else:
            return JsonResponse(login_status, status=201)


class CountSumView(APIView):
    def get(self, request):
        token = request.headers.get('Authorization')
        login_status = is_login_manager(token)
        if login_status['code'] == 200:
            try:
                obj1 = Suggestion.objects.filter(sugg_status=True).all().count()
                obj2 = Suggestion.objects.filter(sugg_status=False).all().count()
                obj3 = Complaint.objects.filter(comp_status=True).all().count()
                obj4 = Complaint.objects.filter(comp_status=False).all().count()
            except Exception as e:
                return Response({'code': 500, "message": '获取总量失败', "error": str(e)})
            data = {
                'sugg_done': obj1,
                'sugg_todo': obj2,
                'comp_done': obj3,
                'comp_todo': obj4
            }
            return Response({'code': 200, 'data': data, 'message': "成功获取"})
        else:
            return Response(login_status)


# 假设response.text是从网页获取的HTML内容
limit_url = "https://jtgl.beijing.gov.cn/"
limit_headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3"}


def getXHNumber(tDate: datetime.datetime, sDate: datetime.datetime):
    nDayNum = tDate.weekday() + 1
    if nDayNum > 5:
        return nDayNum
    nDiff = (tDate - sDate).days / (7 * 13)
    nDiff = math.floor(nDiff) % 5
    nDayNum = 5 - nDiff + nDayNum
    if nDayNum > 5:
        nDayNum -= 5
    return nDayNum


def xianxing():
    # 获取网页信息
    try:
        response = requests.get(limit_url, headers=limit_headers)
        response.encoding = 'utf-8'
        soup = BeautifulSoup(response.text, 'html.parser')
        scripts = soup.find_all('script', attrs={'type': 'text/javascript'})
        # 用于存储Holiday数组的字符串
        holiday_script = ""
        # 查找包含Holiday数组定义的<script>标签
        for script in scripts:
            if script.string and "var Holiday=new Array" in script.string:
                holiday_script = script.string
                break
        # 使用正则表达式从JavaScript代码中提取日期
        Holiday = re.findall(r'"(\d{4}-\d{1,2}-\d{1,2})"', holiday_script)
    except Exception as e:
        return Response({'code': 500, "message": '获取限行信息出错', "error": str(e)})

    sStartDate = '2014-04-14'  # 开始星期，周一的日期
    x = [None, '5和0', '1和6', '2和7', '3和8', '4和9', '-', '-']

    vStartDate = datetime.datetime.strptime(sStartDate, "%Y-%m-%d")
    vToday = datetime.datetime.now()  # 客户端当天时间

    nDayNum1 = getXHNumber(vToday, vStartDate)  # 限行尾号数组值
    vToday += datetime.timedelta(days=1)
    nDayNum2 = getXHNumber(vToday, vStartDate)

    # 判断今天和明天是否为节假日
    for holiday in Holiday:
        tddate = datetime.datetime.strptime(holiday, "%Y-%m-%d")
        if vToday.strftime("%Y-%m-%d") == tddate.strftime("%Y-%m-%d"):
            nDayNum1 = 6
        if (vToday + datetime.timedelta(days=1)).strftime("%Y-%m-%d") == tddate.strftime("%Y-%m-%d"):
            nDayNum2 = 6

    return x[nDayNum1], x[nDayNum2]


class LimitFinal(APIView):  # 用户查询限行信息
    def get(self, request):
        # token = request.headers.get('Authorization')
        # login_status = is_login_user(token)
        # if login_status['code'] == 200:
        try:
            print(xianxing())
            today_limit, tomorrow_limit = xianxing()
            today_matches = re.findall(r'\d+|-', today_limit)
            tomorrow_matches = re.findall(r'\d+|-', tomorrow_limit)
            # 如果仅有一个 '-'，将两个限行值都赋为 '-'
            if today_matches == ['-']:
                today_limit1, today_limit2 = '-', '-'
            else:
                today_limit1, today_limit2 = today_matches[:2]

            if tomorrow_matches == ['-']:
                tomorrow_limit1, tomorrow_limit2 = '-', '-'
            else:
                tomorrow_limit1, tomorrow_limit2 = tomorrow_matches[:2]
        except Exception as e:
            return Response({'code': 500, "message": 'post中获取限行信息出错', "error": str(e)})
        #  构建返回体
        limit_result = {
            "today_limit1": today_limit1,
            "today_limit2": today_limit2,
            "tomorrow_limit1": tomorrow_limit1,
            "tomorrow_limit2": tomorrow_limit2
        }
        return Response({'code': 200, 'data': limit_result, 'message': "成功获取限行数据"})
    # else:
    #     return Response(login_status)
